﻿using Qy.Common;
using Qy.Models;
using Qy.Repository;
using System;
using System.Linq;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;

namespace Qy.Service
{

    [AppService]
    public class ConfigService
    {
        private readonly ConfigRepository configDal;
        private readonly ICacheManager _cacheManager;
        private readonly string cacheKey;
        public ConfigService(ConfigRepository configRepository, ICacheManager cacheManager)
        {
            configDal = configRepository;
            _cacheManager = cacheManager;
            cacheKey = CacheConst.CACHE_KEY_CONFIG;
        }

        /// <summary>
        /// 键名当前列数据
        /// </summary>
        /// <returns></returns>
        public async Task<SytemConfig> GetSytemConfigAsync()
        {
            SytemConfig sytemConfig = _cacheManager.Get<SytemConfig>(cacheKey);
            if (sytemConfig == null)
            {
                var dbget = await configDal.GetAllAsync("name asc");

                var options = new JsonSerializerOptions
                {
                    NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString,
                    Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
                    WriteIndented = true
                };

                Config sys1 = dbget.FirstOrDefault(s => s.Name == "systemInfo");
                SystemInfo systemInfo = JsonSerializer.Deserialize<SystemInfo>(sys1.Data, options);

                Config sys2 = dbget.FirstOrDefault(s => s.Name == "upLoad");
                UpLoadConfig upLoad = JsonSerializer.Deserialize<UpLoadConfig>(sys2.Data, options);

                Config sys3 = dbget.FirstOrDefault(s => s.Name == "commonlyUsed");
                CommonlyUsed commonlyUsed = JsonSerializer.Deserialize<CommonlyUsed>(sys3.Data, options);

                sytemConfig = new()
                {
                    SiteName = systemInfo.SiteName,
                    UnitOfUse = systemInfo.UnitOfUse,
                    SiteUrl = systemInfo.SiteUrl,
                    Description = systemInfo.Description,
                    Copyright = systemInfo.Copyright,
                    Beian = systemInfo.Beian,

                    BaseDir = upLoad.BaseDir,
                    ImageDir = upLoad.ImageDir,
                    ImageSize = upLoad.ImageSize,
                    ImageExt = upLoad.ImageExt,
                    FileDir = upLoad.FileDir,
                    FileExt = upLoad.FileExt,
                    FileSize = upLoad.FileSize,

                    Marks = commonlyUsed.Marks,
                };
                _cacheManager.Set(cacheKey, sytemConfig, TimeSpan.FromDays(31));
            }

            return sytemConfig;
        }

        /// <summary>
        /// 从缓存中获取上传设置
        /// </summary>
        /// <returns></returns>
        public async Task<UpLoadConfig> GetByUploadAsync()
        {
            SytemConfig sytemConfig = await GetSytemConfigAsync();

            UpLoadConfig upLoad = new()
            {
                BaseDir = sytemConfig.BaseDir,
                ImageDir = sytemConfig.ImageDir,
                ImageSize = sytemConfig.ImageSize,
                ImageExt = sytemConfig.ImageExt,
                FileDir = sytemConfig.FileDir,
                FileExt = sytemConfig.FileExt,
                FileSize = sytemConfig.FileSize
            };
            return upLoad;
        }

        /// <summary>
        /// 从缓存中获取系统设置
        /// </summary>
        /// <returns></returns>
        public async Task<SystemInfo> GetBySystemInfoAsync()
        {
            SytemConfig sytemConfig = await GetSytemConfigAsync();
            SystemInfo systemInfo = new()
            {
                SiteName = sytemConfig.SiteName,
                UnitOfUse = sytemConfig.UnitOfUse,
                SiteUrl = sytemConfig.SiteUrl,
                Description = sytemConfig.Description,
                Copyright = sytemConfig.Copyright,
                Beian = sytemConfig.Beian,
            };
            return systemInfo;
        }

        /// <summary>
        /// 根据属性 获取 对应值
        /// </summary>
        /// <returns></returns>
        public async Task<string> GetByFieldNameAsync(string FieldName)
        {
            return ReflexHelper.GetModelValue(FieldName, await GetSytemConfigAsync());
        }

        /// <summary>
        /// 批量更新
        /// </summary>
        /// <param name="config"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public async Task<int> UpdateByNameAsync(SytemConfig data)
        {
            SystemInfo systemInfo = new()
            {
                SiteName = data.SiteName,
                UnitOfUse = data.UnitOfUse,
                SiteUrl = data.SiteUrl,
                Description = StringUtility.StringReplaceNRT(data.Description),
                Copyright = data.Copyright,
                Beian = data.Beian,
            };
            UpLoadConfig upLoad = new()
            {
                BaseDir = data.BaseDir,
                ImageDir = data.ImageDir,
                ImageSize = data.ImageSize,
                ImageExt = data.ImageExt,
                FileDir = data.FileDir,
                FileExt = data.FileExt,
                FileSize = data.FileSize
            };
            CommonlyUsed commonlyUsed = new()
            {
                Marks = data.Marks,
            };

            var options = new JsonSerializerOptions
            {
                Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
                WriteIndented = true
            };

            string jsonA = JsonSerializer.Serialize(systemInfo, options);
            string jsonB = JsonSerializer.Serialize(upLoad, options);
            string jsonC = JsonSerializer.Serialize(commonlyUsed, options);

            int res = await configDal.UpdateByNameAsync(jsonA, jsonB, jsonC);
            if (res > 0)
            {
                _cacheManager.Remove(cacheKey);
                return res;
            }
            else
            {
                return 0;
            }


        }
    }
}
